/*-------------------------------------------------
*File name: WindowFederate.cu
*Author: Tran Van Hoang
*Date: 23-04-2015
*--------------------------------------------------*/
#include <X11/Xlib.h>
#include <X11/Xutil.h>	

#include "RTI.hh"
#include <cstdlib>
#include <iostream>
#include <string.h>
#include <cassert>
#include "WindowFederate.h"
#include "view.h"
#include "cuda.h"
#include "federation.h"

//Classes
#define CLA_FOREST_NODE "ForestNode"
#define CLA_RIVER_NODE "RiverNode"
#define CLA_SENSOR_NODE "SensorNode"
//Attributes
#define ATT_POSITION_X "PositionX"
#define ATT_POSITION_Y "PositionY"
#define ATT_DENSITY "Density"
#define ATT_STATE "State"
#define ATT_IMAGEEXTENTX "ImageExtentX"
#define ATT_IMAGEEXTENTY "ImageExtentY"

using std::string;

int main()
{
	// create and run the federate
	WindowFederate *windowFederate;
	
	windowFederate = new WindowFederate(WINDOW_FEDERATE_NAME, FEDERATION_FILE_NAME);
	windowFederate->runFederate(FEDERATION_NAME);
	
	delete windowFederate;
	return 0;
}
//--------------------------------------------------------------------------------------------
/** Main simualation
**/
#include <unistd.h>
#include <cuda.h>
#include <Xlib.h>
#include "dataRiver.cu"
#include "dataForest.cu"
#include "dataSensorNet.cu"

#define WINDOW_TITLE "Cellular Automata with CUDA: Observer Federate"

const int NUMBER_CYCLE = FEDERATION_CYCLE;

int NODE_NUMBER_SENSOR = sizeof(NetCells)/sizeof(CellArray);

Colormap colormap;
Display *dsp;
Window win;
GC gc;
int plotSize;
unsigned long white, black;
SensorNode *sensorNode;

void WindowFederate::displaying()
{
	int NSize;

	sensorNode = (SensorNode*) malloc(NODE_NUMBER_SENSOR * sizeof(SensorNode));

	plotSize = 1;
	NSize = 256;
	dsp = XOpenDisplay(NULL);

	if (dsp == NULL)
	{ 
		printf("\n### Cannot connect to server.\n");
		return;
	}

	colormap = DefaultColormap(dsp, 0);

	int screenNumber = DefaultScreen(dsp);
	white = WhitePixel(dsp, screenNumber);
	black = BlackPixel(dsp, screenNumber);	

	win = XCreateSimpleWindow(dsp,
				DefaultRootWindow(dsp),
				50, 50,// origin
				NSize*plotSize*3, NSize*plotSize*3,// size
				0, black,//border
				COLOR_BACKGROUND//background
	);

	XStoreName(dsp, win, WINDOW_TITLE);
	XMapWindow(dsp, win);

	gc = XCreateGC(dsp, win, 0, NULL);	
	long eventMask = StructureNotifyMask;
	XSelectInput(dsp, win, eventMask);
	XEvent evt;

	///Displaying River
	for (int i = 0; i < NODE_NUMBER_RIVER; i++)
	{
	     showCell(RiverCells[i], dsp, colormap, win, gc, plotSize, -1);
	}

	///Displaying Forest
	for (int i = 0; i < NODE_NUMBER_FOREST; i++)
	{
	     showCell(ForestCells[i], dsp, colormap, win, gc, plotSize, -1);
	}

	for (int i = 0; i < NODE_NUMBER_SENSOR; i++)
	{
	    //NetCells array comes from dataSensorNet.cu file
	    showCellNetwork(NetCells[i], dsp, colormap, win, gc, plotSize, SENSOR_NET_NORMAL, RANGE_SENSING, RANGE_COMMUNICATION);
	    sensorNode[i].sensorState = SENSOR_NET_NORMAL;
	}

	printf("\n-- Click on the window to continue!\n");
	do
	{
		XNextEvent(dsp, &evt);
	}while(evt.type != MapNotify);	

	RTIfedTime nextStep;
	int state;
	for (int i = 0; i < NUMBER_CYCLE; i++)
	{
	    //Updating sensors on the screen
	    for (int j = 0; j < NODE_NUMBER_SENSOR; j++)
	    {
		state = sensorNode[j].sensorState;
	        showCellNetwork(NetCells[j], dsp, colormap, win, gc, plotSize, state, RANGE_SENSING, RANGE_COMMUNICATION);
	    }

	    nextStep = this->timeAdvance(1.0);

	    printf("=> Step %d finished!\n  Refreshing view ...\n", i + 1);
	}

	printf("\n-- Click on the window to continue!\n");

	eventMask = ButtonPressMask | ButtonReleaseMask;

	XSelectInput(dsp, win, eventMask);
	do{
		XNextEvent(dsp, &evt);
	}while(evt.type != ButtonRelease);

	//Releasing resources
	XDestroyWindow(dsp, win);
	XCloseDisplay(dsp);
}

//----------------------------------------------------------------------------
/**Constructor
**/
WindowFederate::WindowFederate(std::string federate_name, std::string fdd_name):
	rtiamb(),
	federateName(federate_name),
	fddName(fdd_name),
	handle(0),
	creator(false),
	nbTicks(0),
	regulating(false),
	constrained(false),
	notimestamp(false),
	localTime(0.0),
	TIME_STEP(1.0),
	joined(false)
{
}
//-----------------------------------------------------------------------------
/**Destructor
*/
WindowFederate::~WindowFederate()
	throw (RTI::FederateInternalError)
{
}
//-----------------------------------------------------------------------------
/* Main Simulation Method
**/

void WindowFederate::runFederate(std::string federation_name)
{
	int autostart = 0;
	federationName = federation_name;
	//1. Creating the RTIambassador
	////finished in another way
	//2. Creating and joining to the federation
	this->createFederation(federationName);
	this->joinFederation(federationName);
	//3. Initialiazing the handles
	this->getHandles();
	//4. Annoucing the sync point
	// Announce a sync point to get everyone on the same page. if the point
	// has already been registered, we'll get a callback saying it failed,
	// but we don't care about that, as long as someone registered it
	this->pause();
	// tell the RTI we are ready to move past the sync point and then wait
	// until the federation has synchronized on
	//5. Achieving the point and wait for synchronization
	this->synchronize(autostart);
	//7. Publishing and subscribing
	this->setTimeRegulation(true, true);
	this->publishAndSubscribe();
	//8. Registering an object to update
	//RTI::ObjectHandle objectHandle = rtiamb.registerObjectInstance(ForestNodeClassID, RIVER_FEDERATE_NAME);
	//9. Doing the main simulation loop
	this->displaying();
	//10. Deleting the object
	//rtiamb.deleteObjectInstance(objectHandle, NULL);
	//11. Resigning from the federation
	rtiamb.resignFederationExecution(RTI::NO_ACTION);
	printf("\n-- Resigned from Federation!\n");
	//12. Destroying the federation
	try{
		rtiamb.destroyFederationExecution(FEDERATION_NAME);
		printf("\n-- Federation %s was destroyed!\n", FEDERATION_NAME);
	}catch(RTI::FederationExecutionDoesNotExist e)
	{
	     printf("\n### No need to destroy federation %s, it doesn't exist!\n", FEDERATION_NAME);
	}catch(RTI::FederatesCurrentlyJoined ex)
	{
	     printf("\n### Federate still joined, can't destroy federation %s!\n", FEDERATION_NAME);
	}
	//13. Cleaning up
	
}
//-----------------------------------------------
/** timeAdvance request
**/
RTIfedTime WindowFederate::timeAdvance(RTIfedTime time_step)
{
	granted = false;

	try{
	    rtiamb.queryFederateTime(localTime);
	}catch(RTI::Exception& e)
	{
	      printf("\n### Exception requesting for federate local time");
	}

	try{
	   RTIfedTime time_at(localTime.getTime()+TIME_STEP.getTime());
	   printf("\n-- Time_at: %.2f - localtime: %.2f - timestep: %.2f\n", 
			time_at.getTime(), ((RTIfedTime&)localTime).getTime(), ((RTIfedTime&)TIME_STEP).getTime());
	   granted = false;
	   rtiamb.timeAdvanceRequest(time_at);

	}catch(RTI::Exception& e)
	{
		printf("\n### Exception with timeAdvancerequest!\n");
	}

	while(!granted)
	{
	     try{
	     	tick();
	     }catch(RTI::Exception& e)
	     {
		printf("\n### Exception ticking the RTI!\n");		
	     }
	}

	RTIfedTime next_step(localTime + TIME_STEP);
	return next_step;
}
//---------------------------------------------------------------------------------------
/** Rigister object
*****/
RTI::ObjectHandle WindowFederate::registerObject()
{
	return rtiamb.registerObjectInstance(ForestNodeClassID);
}

//---------------------------------------------------------------------------------------
/** Getting the federate handle
*/
RTI::FederateHandle WindowFederate::getHandle() const
{
	return handle;
}
//---------------------------------------------------------------------------------------
/** This method will get all the relevant handle information from the RTIambassador
***/
void WindowFederate::getHandles()
{
	printf("\n-- Getting handles ...\n");
	//Getting classes
	ForestNodeClassID = rtiamb.getObjectClassHandle(CLA_FOREST_NODE);
	RiverNodeClassID = rtiamb.getObjectClassHandle(CLA_RIVER_NODE);
	SensorNodeClassID = rtiamb.getObjectClassHandle(CLA_SENSOR_NODE);
	printf("\n-- ForestNodeClassID = %d, RiverNodeClassID = %d\n", (int) ForestNodeClassID, (int) RiverNodeClassID);
	//Getting attributes
	AttrXID = rtiamb.getAttributeHandle(ATT_POSITION_X, ForestNodeClassID);
	AttrYID = rtiamb.getAttributeHandle(ATT_POSITION_Y, ForestNodeClassID);
	AttrStateID = rtiamb.getAttributeHandle(ATT_STATE, ForestNodeClassID);
	AttrImageExtentXID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTX, ForestNodeClassID);
	AttrImageExtentYID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTY, ForestNodeClassID);

	printf("\n-- AttrXD = %d, AttrYID = %d, AttrDensityID = %d, AttrStateID = %d, AttrImageExtentXID = %d, ImageExtentYID = %d\n", 
		(int) AttrXID, (int) AttrYID, (int) RiverAttrDensityID, (int) AttrStateID, (int) AttrImageExtentXID, (int) AttrImageExtentYID);	
	RiverAttrXID = rtiamb.getAttributeHandle(ATT_POSITION_X, RiverNodeClassID);
	RiverAttrYID = rtiamb.getAttributeHandle(ATT_POSITION_Y, RiverNodeClassID);
	RiverAttrDensityID = rtiamb.getAttributeHandle(ATT_DENSITY, RiverNodeClassID);
	RiverAttrImageExtentXID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTX, RiverNodeClassID);
	RiverAttrImageExtentYID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTY, RiverNodeClassID);

	SensorAttrXID = rtiamb.getAttributeHandle(ATT_POSITION_X, SensorNodeClassID);
	SensorAttrYID = rtiamb.getAttributeHandle(ATT_POSITION_Y, SensorNodeClassID);
	SensorAttrStateID = rtiamb.getAttributeHandle(ATT_STATE, SensorNodeClassID);
	SensorAttrImageExtentXID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTX, SensorNodeClassID);
	SensorAttrImageExtentYID = rtiamb.getAttributeHandle(ATT_IMAGEEXTENTY, SensorNodeClassID);

}
//-----------------------------------------------------------------------------------------
/** Blocking untils the user press enter
***/
void WindowFederate::waitForUser()
{
	printf("\n>>>>>>>>>> Press ENTER to continue <<<<<<<<<<\n");	
	getchar();
}
//-----------------------------------------------------------------------------------------
/** Synchronizing with other federates
****/
void WindowFederate::synchronize(int auto_start)
{	
	printf("\n-- Synchronizing ...\n");
	if (creator == true)
	{
	    if (auto_start == 0)
	    {	
		printf("\n>>>>>>>>>>>> Press ENTER to start execution <<<<<<<<<<<<<\n");
		getchar();
	    }
	    else
	    {
		while (auto_start >= 0)
		{
		      sleep(0);
		      printf("\r-- Autostart: %5d", auto_start);
		      fflush(stdout);
		      auto_start--;
		}
		printf("\n");
	    }
	    printf("\n-- Creator can resume execution ...\n");
	    while(paused == false)
	    {
		try{
		    printf("\n-- Not paused!\n");
		    tick();
		}
		catch(RTI::Exception &e)
		{
		     printf("\n** Exception: Ticking the RTI: %d\n", (int) &e);
		     throw;
		}
	    }
	    printf("\n-- Execution is paused!\n");
	    
	    try {
		rtiamb.synchronizationPointAchieved("Init");
		printf("\n-- Pause is achieved.\n");
	    }
	    catch(RTI::Exception &e)
	    {
	     	printf("\n** Exception: Achieving a synchronization point by creator: %d\n", (int) &e);
	    }

	    while (paused == true)
	    {
		try{
		    tick();
		}
		catch(RTI::Exception &e)
		{
		     printf("\n** Exception: Ticking the RTI: %d\n", (int) &e);
		     throw;
		}
	    }
	}
	else//Not creator
	{
	    if (auto_start != 0)
	    {
		printf("\n-- Ignoring autostart because this federate is not creator\n");
	    }

	    printf("\n-- Synchronizing ...\n");
	    
	    if (paused == false)
	    {
		printf("\n-- Federate is not paused: too early!\n");
		while(paused == false)
		{
		     try{
			tick();
		     }
		     catch(RTI::Exception &e)
		     {
			  printf("\n** Exception: Ticking the RTI: %d\n", (int) &e);
		     	  throw;
		     }
		}
	    }
	    printf("\n-- Federate is paused.\n");
	    try {
		rtiamb.synchronizationPointAchieved("Init");
		printf("\n-- Pause is achieved.\n");
	    }
	    catch(RTI::Exception &e)
	    {
	     	printf("\n** Exception: Achieving a synchronization point by creator: %d\n", (int) &e);
	    }
	    printf("\n-- Federation is waiting until ending the pause ...\n");
	    while(paused == true)
	    {
		try{
		   tick();
		}
		catch(RTI::Exception &e)
		{ 
		       printf("\n** Exception: Ticking the RTI: %d\n", (int) &e);
		       throw;
		}
	    }	
	    printf("\n-- End of pause.\n");
	}
	printf("\n-- Federation is synchronized.\n");
}
//------------------------------------------------
/**This method try to create a new federation in the case of no federation. Ortherwise, 
**/
void WindowFederate::createFederation(std::string federation_name)
{
	try{
	   rtiamb.createFederationExecution(federation_name.c_str(), fddName.c_str());
	   printf("\n-- Federation execution named %s is created!\n", federation_name.c_str());
	   creator = true;
	}
	catch (RTI::FederationExecutionAlreadyExists &e){
	   printf("-- Exception: %s Reason is: %s. OK I can join it\n", e._name, e._reason);
	}
	catch (RTI::CouldNotOpenFED &e){
	   printf("** Federate %s : ERROR: %s Reason is: %s\n", federateName.c_str(), e._name, e._reason);
	   delete &rtiamb;
	   exit(0);
	}

}
//------------------------------------------------
/**It will join to the existing federation in case of the unjoined state.
*@federation_name: name of federation.
*
**/
void WindowFederate::joinFederation(std::string federation_name)
{
	//Joining the federation
	
	if (joined == false)
	{
	   try{
		handle = rtiamb.joinFederationExecution(federateName.c_str(), federation_name.c_str(), this);
		joined = true;		
		printf("-- Federate %s was joined to federation named %s!\n", federateName.c_str(), federation_name.c_str());
	   }
	   catch (RTI::FederateAlreadyExecutionMember &e){
		printf("## Exception: Federate %s already exists!\n", federateName.c_str());
		throw;
	   }
	   catch (RTI::FederationExecutionDoesNotExist &e){
		printf("** Exception: Federate %s : FederationExecutionDoesNotExists! \n", federateName.c_str());
	   }
	   catch (RTI::Exception &e){
		printf("** Federate %s : Join Federation Execution failed!\n", federateName.c_str());
	   }
	}
	
}

//-------------------------------------------------------------------------
/**This method allow creator to put federation in pause!
***/

void WindowFederate::pause()
{
	if (creator == true)
	{
	   printf("\n-- Pause requested.\n");
	   try{
		rtiamb.registerFederationSynchronizationPoint("Init", "-- Waiting for all federates ... \n");
		// Wait for user to kick us off
	   }
	   catch(RTI::Exception &e){
		printf("## Federate %s : Register Synchronization Point failed!\n", federateName.c_str());
	   }
	}
}

//---------------------------------------------------------------------
/** Ticking the RTI
**/
void WindowFederate::tick()
{
	printf("\r-- Tick...");
	rtiamb.tick();
	nbTicks++;
}

void WindowFederate::publishAndSubscribe()
{
	//Get all calss and attributes handles
	int nbAttribute = 6;
	RTI::AttributeHandleSet *attributes = RTI::AttributeHandleSetFactory::create(nbAttribute);
	attributes->add(AttrXID);
	attributes->add(AttrYID);
	attributes->add(AttrStateID);
	attributes->add(AttrImageExtentXID);
	attributes->add(AttrImageExtentYID);
	printf("\n-- Subscribing: class %d -  Attributes: %d, %d, %d, %d, %d ...\n", 
		(int) ForestNodeClassID, (int) AttrXID, (int) AttrYID, (int) AttrStateID, (int) AttrImageExtentXID, (int) AttrImageExtentYID);
	//Subcribing to Node objects
	rtiamb.subscribeObjectClassAttributes(ForestNodeClassID, *attributes, RTI::RTI_TRUE);

	attributes = RTI::AttributeHandleSetFactory::create(nbAttribute);
	attributes->add(RiverAttrXID);
	attributes->add(RiverAttrYID);
	attributes->add(RiverAttrDensityID);
	attributes->add(RiverAttrImageExtentXID);
	attributes->add(RiverAttrImageExtentYID);

	rtiamb.subscribeObjectClassAttributes(RiverNodeClassID, *attributes, RTI::RTI_TRUE);

	attributes = RTI::AttributeHandleSetFactory::create(nbAttribute);
	attributes->add(SensorAttrXID);
	attributes->add(SensorAttrYID);
	attributes->add(SensorAttrStateID);
	attributes->add(SensorAttrImageExtentXID);
	attributes->add(SensorAttrImageExtentYID);

	rtiamb.subscribeObjectClassAttributes(SensorNodeClassID, *attributes, RTI::RTI_TRUE);

	printf("\n-- Subscribing done!\n");
}

void WindowFederate::setTimeRegulation(bool start_constrained, bool start_regulating)
{
        printf("\n-- Time Regulation setup ...\n");

        if (start_constrained == true)
        {
           if (!constrained)
           {
                rtiamb.enableTimeConstrained();
                constrained = true;
                printf("\n-- Time Constrained enabled.\n");
           }
        }
        else
        {
            if (constrained)
            {
                rtiamb.disableTimeConstrained();
                constrained = false;
                printf("\n-- Time Constrained disabled.\n");
            }
        }

        if (start_regulating == true)
        {
           if (!regulating)
           {
                for (;;)
                {
                    rtiamb.queryFederateTime(localTime);
                    try {
                        rtiamb.enableTimeRegulation(localTime, TIME_STEP);
                        regulating = true;
                        break;
                    }catch(RTI::FederationTimeAlreadyPassed)
                    {
                        rtiamb.queryFederateTime(localTime);
                        RTIfedTime requestTime(((RTIfedTime&)localTime).getTime());
                        requestTime += TIME_STEP;

                        granted = false;
                        while(!granted)
                        {
                             try{
                                tick();
                             }catch(RTI::RTIinternalError)
                             {
                                printf("\n-- RTIinternalError Raised in tick.\n");
                                exit(-1);
                             }
                        }
                    }catch(RTI::RTIinternalError)
                    {
                        printf("\n-- RTIinternalError Raised in setTimeRegulating.\n");
                        exit(-1);
                    }
                }
           }
        }
        else
        {
            if (regulating)
            {
                rtiamb.disableTimeRegulation();
                regulating = false;
            }
        }
}

void WindowFederate::checkRegions()
{

}

void WindowFederate::sendInteraction(double dx, double dy, const RTI::FedTime& InteractionTime, RTI::ObjectHandle id)
{
}

void WindowFederate::sendInteraction(double, double, RTI::ObjectHandle)
{
	
}

void WindowFederate::sendUpdate(Node node, const RTI::FedTime & UpdateTime, RTI::ObjectHandle id)
{
}

//============================================================================
// FEDERATE AMBASSDOR CALLBACKS
//============================================================================
///////////////////////////////////////////////////////////////////////////////
/////////////////////// Synchronization Point Callbacks ///////////////////////
///////////////////////////////////////////////////////////////////////////////
void WindowFederate::synchronizationPointRegistrationSucceeded(const char* label)
	throw(RTI::FederateInternalError)
{
	printf("\n-- Successfully registered sync point: %s\n", label);
}

void WindowFederate::synchronizationPointRegistrationFailed(const char* label)
	throw(RTI::FederateInternalError)
{
	printf("\n-- Failed to register sync point: %s\n", label);
}

void WindowFederate::announceSynchronizationPoint(const char *label, const char */*tag*/)
    throw (RTI::FederateInternalError)
{
	if (strcmp(label, "Init") == 0)
	{
	    printf("\n-- Synchronization point announced: %s\n", label);
	    paused = true;
	}
}

void WindowFederate::federationSynchronized(const char *label)
	throw(RTI::FederateInternalError)
{
	if (strcmp(label, "Init") == 0)
	{
	   printf("\n-- Federation Synchronized: %s\n", label);
	   paused = false;
	}
}


// ----------------------------------------------------------------------------
/** Callback : discover object instance
 */
void
WindowFederate::discoverObjectInstance(RTI::ObjectHandle theObject,
				RTI::ObjectClassHandle theObjectClass,
				const char */*theObjectName*/)
    throw (RTI::CouldNotDiscover, RTI::ObjectClassNotKnown, 
	   RTI::FederateInternalError)
{
	printf("\n-- discoverObjectInstance\n");
}

//-------------------------------------------------------------------------------
/** Callback: receive interaction
****/
void WindowFederate::receiveInteraction(RTI::InteractionClassHandle theInteraction,
                            const RTI::ParameterHandleValuePairSet & theParameters,
			    const RTI::FedTime& /*theTime*/,
                            const char */*theTag*/,
			    RTI::EventRetractionHandle /*theHandle*/)
        		throw ( RTI::InteractionClassNotKnown, 
				RTI::InteractionParameterNotKnown,
				RTI::InvalidFederationTime,
               			RTI::FederateInternalError)
{
}

void WindowFederate::reflectAttributeValues(RTI::ObjectHandle theObject,
                                const RTI::AttributeHandleValuePairSet& theAttributes,
                                const RTI::FedTime& theTime, 
				const char *theTag,
                                RTI::EventRetractionHandle theHandle)
        		throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown,
               			RTI::InvalidFederationTime, RTI::FederateInternalError)
{
	libhla::MessageBuffer buffer;

	printf("\n-- Reflect attribute values with time: object=%d, tag=%s, time=%.2f", 
			(int) theObject, theTag, convertTime(theTime));

	int nbAttributes = 0;
	nbAttributes = theAttributes.size();
	printf("\n-- Number of attributes: %d \n", nbAttributes);

	int x, y, width, height, state;
	float density;
	RTI::ULong i, length;

	if (dsp == NULL)
	{
		printf("\n### Cannot connect to server.\n");
		exit(-1);
	}

	if (strcmp(theTag, FOREST_FEDERATE_NAME) == 0)
	{
	   for (i = 0; i < nbAttributes; i++)
	   {
	    	RTI::AttributeHandle attHandle = theAttributes.getHandle(i);
	    	length = theAttributes.getValueLength(i);
	    	buffer.resize(length);
	    	buffer.reset();
	    	theAttributes.getValue(i, static_cast<char*>(buffer(0)), length);
	    	buffer.assumeSizeFromReservedBytes();
	    
	    	if (attHandle == AttrXID)
	    	{
		   x = buffer.read_int32();
	    	}else if (attHandle == AttrYID)
	    	{
		   y = buffer.read_int32();
	    	}else if (attHandle == AttrImageExtentXID)
	    	{
		   width = buffer.read_int32();
	    	}else if (attHandle == AttrImageExtentYID)
	    	{
		   height = buffer.read_int32();
	    	}else if (attHandle == AttrStateID)
	    	{
		   state = buffer.read_int32();

		   ///Displaying received data on window
		   CellArray cell;
		   cell.position.x = x;
		   cell.position.y = y;
		   cell.image.extent.width = width;
		   cell.image.extent.height = height;
	     	   showCellForest(cell, dsp, colormap, win, gc, plotSize, state);
	    	}else
	    	   printf("\n-- Handle unkown\n");
	    }
	}
	else if(strcmp(theTag, RIVER_FEDERATE_NAME) == 0)
	{
		int index;
	   	for (i = 0; i < nbAttributes; i++)
	   	{
	    	    RTI::AttributeHandle attHandle = theAttributes.getHandle(i);
	    	    length = theAttributes.getValueLength(i);
	    	    buffer.resize(length);
	    	    buffer.reset();
	    	    theAttributes.getValue(i, static_cast<char*>(buffer(0)), length);
	    	    buffer.assumeSizeFromReservedBytes();
	    
	     	    if (attHandle == RiverAttrXID)
	    	    {
		   	x = buffer.read_int32();
	    	    }else if (attHandle == RiverAttrYID)
	    	    {
		   	y = buffer.read_int32();
	    	   }else if (attHandle == RiverAttrImageExtentXID)
	    	   {
		   	width = buffer.read_int32();
	    	   }else if (attHandle == RiverAttrImageExtentYID)
	    	   {
		   	height = buffer.read_int32();
	    	   }else if (attHandle == RiverAttrDensityID)
	    	   {
		   	density = (int) (buffer.read_double() * 100.0);

		   	///Displaying received data on window
		   	CellArray cell;
		   	cell.position.x = x;
		  	cell.position.y = y;
		   	cell.image.extent.width = width;
		   	cell.image.extent.height = height;
			index = FindIndexPosition(cell.position, RiverCells, NODE_NUMBER_RIVER);
	     		showCellDensity(RiverCells[index], dsp, colormap, win, gc, plotSize, density);
	    	   }else
	    	   	printf("\n-- Handle unkown\n");
	
	       	}
	}
	else if(strcmp(theTag, NETWORK_FEDERATE_NAME) == 0)
	{
		int index;
	   	for (i = 0; i < nbAttributes; i++)
	   	{
	    	    RTI::AttributeHandle attHandle = theAttributes.getHandle(i);
	    	    length = theAttributes.getValueLength(i);
	    	    buffer.resize(length);
	    	    buffer.reset();
	    	    theAttributes.getValue(i, static_cast<char*>(buffer(0)), length);
	    	    buffer.assumeSizeFromReservedBytes();
	    
	     	    if (attHandle == RiverAttrXID)
	    	    {
		   	x = buffer.read_int32();
	    	    }else if (attHandle == RiverAttrYID)
	    	    {
		   	y = buffer.read_int32();
	    	   }else if (attHandle == RiverAttrImageExtentXID)
	    	   {
		   	width = buffer.read_int32();
	    	   }else if (attHandle == RiverAttrImageExtentYID)
	    	   {
		   	height = buffer.read_int32();
	    	   }else if (attHandle == RiverAttrDensityID)
	    	   {
		   	state = buffer.read_int32();
		   	CellArray cell;
		   	cell.position.x = x;
		  	cell.position.y = y;
		   	cell.image.extent.width = width;
		   	cell.image.extent.height = height;
			
			index = FindIndexPosition(cell.position, NetCells, NODE_NUMBER_SENSOR);
			if (state == SENSOR_NET_URGENT)
			{
	    		    showCellNetwork(NetCells[index], dsp, colormap, win, gc, plotSize, SENSOR_NET_URGENT, RANGE_SENSING, RANGE_COMMUNICATION);
			    sensorNode[index].sensorState = SENSOR_NET_URGENT;
			}else
			{
			    sensorNode[index].sensorState = SENSOR_NET_NORMAL;
			}
			
	    	   }else
	    	   	printf("\n-- Handle unkown\n");
	
	       	}
	   }

}

void WindowFederate::reflectAttributeValues(RTI::ObjectHandle theObject,
                                const RTI::AttributeHandleValuePairSet & theAttributes,
                                const char *theTag)
       	 		throw (RTI::ObjectNotKnown, RTI::AttributeNotKnown,
               			RTI::FederateInternalError)
{
	printf("\n--reflectAttributeValues\n");
}

void WindowFederate::receiveInteraction(RTI::InteractionClassHandle,
                            const RTI::ParameterHandleValuePairSet &,
                            const char *)
        		throw (RTI::InteractionClassNotKnown, RTI::InteractionParameterNotKnown,
               			RTI::FederateInternalError)
{
	printf("\n--ReceiveInteraction\n");
}
void WindowFederate::removeObjectInstance(RTI::ObjectHandle theObject, const RTI::FedTime& theTime,
                              const char *theTag,
                              RTI::EventRetractionHandle theHandle)
        		throw (RTI::ObjectNotKnown, RTI::InvalidFederationTime, RTI::FederateInternalError)
{
	printf("\n--removeObjectInstance\n");
}

void WindowFederate::removeObjectInstance(RTI::ObjectHandle, const char *)
        		throw (RTI::ObjectNotKnown, RTI::FederateInternalError)
{

}

//-----------------------------------------------------------------------------------------
/** Callback time advanced granted
**/
void WindowFederate::timeAdvanceGrant(const RTI::FedTime& theTime)
	throw (RTI::FederateInternalError, RTI::TimeAdvanceWasNotInProgress,
               			RTI::InvalidFederationTime)
{
	granted = true;
	localTime = theTime;
	printf("\n-- Time advanced, local time is now %.2f.\n", localTime.getTime());
}

double WindowFederate::convertTime(const RTI::FedTime& theTime)
{
	RTIfedTime time = (RTIfedTime)theTime;
	return time.getTime();
}

